#ifndef __REG_H__
#define __REG_H__

#include "common.h"

// 在 CPU_state 结构体定义后添加以下内容

/* EFLAGS 寄存器访问接口 */
#define eflags_val (cpu.eflags.val)          // 整型访问
#define eflags_CF  (cpu.eflags.flags.CF)     // 进位标志
#define eflags_ZF  (cpu.eflags.flags.ZF)     // 零标志
#define eflags_SF  (cpu.eflags.flags.SF)     // 符号标志
#define eflags_OF  (cpu.eflags.flags.OF)     // 溢出标志
#define eflags_IF  (cpu.eflags.flags.IF)     // 中断使能标志

//定义了三个枚举类型，分别表示32位、16位和8位寄存器的索引
enum { R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI };
enum { R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI };
enum { R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH };

/* TODO: Re-organize the `CPU_state' structure to match the register
 * encoding scheme in i386 instruction format. For example, if we
 * access cpu.gpr[3]._16, we will get the `bx' register; if we access
 * cpu.gpr[1]._8[1], we will get the 'ch' register. Hint: Use `union'.
 * For more details about the register encoding scheme, see i386 manual.
 */

//CPU寄存器状态结构体
typedef struct {
  union{
    union {
      uint32_t _32;
      uint16_t _16;
      uint8_t _8[2];
    } gpr[8];

    /* Do NOT change the order of the GPRs' definitions. */

    /* In NEMU, rtlreg_t is exactly uint32_t. This makes RTL instructions
    * in PA2 able to directly access these registers.
    */
   struct{
    rtlreg_t eax, ecx, edx, ebx, esp, ebp, esi, edi;
   };
  };
  vaddr_t eip;
  union {
    uint32_t val;
    struct {
      uint32_t CF :1;  // 位 0: Carry Flag
      uint32_t    :1;  // 位 1: 保留
      uint32_t    :4;  // 位 2~5: X
      uint32_t ZF :1;  // 位 6: Zero Flag
      uint32_t SF :1;  // 位 7: Sign Flag
      uint32_t    :1;  // 位 8: X
      uint32_t IF :1;  // 位 9: Interrupt Enable Flag
      uint32_t    :1;  // 位 10: X
      uint32_t OF :1;  // 位 11: Overflow Flag
      uint32_t    :20; // 位 12-31: X
    };
  } eflags;

  struct {
    uint16_t limit;  // IDT的界限
    uint32_t base;   // IDT的线性基地址
  } idtr;

  uint32_t CS;
  uint32_t CR0;
  uint32_t CR3;
  bool INTR;
} CPU_state;

extern CPU_state cpu;

static inline int check_reg_index(int index) {
  assert(index >= 0 && index < 8);
  return index;
}

//寄存器访问宏
#define reg_l(index) (cpu.gpr[check_reg_index(index)]._32)
#define reg_w(index) (cpu.gpr[check_reg_index(index)]._16)
#define reg_b(index) (cpu.gpr[check_reg_index(index) & 0x3]._8[(index) >> 2])

//定义了三个字符串数组，分别存储32位、16位和8位寄存器的名称
extern const char* regsl[];
extern const char* regsw[];
extern const char* regsb[];

//根据寄存器的索引和宽度（1字节、2字节、4字节）返回对应的寄存器名称
static inline const char* reg_name(int index, int width) {
  assert(index >= 0 && index < 8);
  switch (width) {
    case 4: return regsl[index];
    case 1: return regsb[index];
    case 2: return regsw[index];
    default: assert(0);
  }
}

#endif
